#include<iostream>
#include "common.hpp"

int main()
{
    // 1. 创建key，用于识别共享内存
    key_t k = ftok(PATH_NAME, PROG_ID);
    if(k == -1)  
    {
        perror("Clinet# ftok");
        exit(1);
    }
    log("Client# get key done", DEBUG) << "key:" << TransToHex(k) << std::endl;

    // 2. 打开共享内存
    // 最后一个参数取0表示只能打开现有的共享内存，不存在就报错
    int shmid = shmget(k, SIZE, 0);   
    if(shmid == -1)
    {
        perror("Clinet# shmid");
        exit(2);
    }
    log("Client# get shm done", DEBUG) << "shmid:" << shmid << std::endl;
    //sleep(7);

    // 3. 将共享内存与进程地址空间相关联
    char* shmaddr = (char*)shmat(shmid, nullptr, 0);
    if(shmaddr == nullptr)
    {
        perror("Client# shmat");
        exit(3);
    }
    log("Client# attach shm done", DEBUG) << "shmid:" << shmid << std::endl;
    //sleep(7);

    // 进程间通信代码
    int fd = OpenFifo(PATH_NAME, WRITE);
    while(true)
    {
        std::cout << "Please input the message: > " << std::endl;;
        ssize_t sz = read(0, shmaddr, SIZE - 1);
        WakeUp(fd);
        if(sz > 0)
        {
            shmaddr[sz - 1] = '\0';
            if(strcmp(shmaddr, "quit") == 0) break;
        }
    }

    // char ch = 'a';
    // for(; ch <= 'd'; ++ch)
    // {
    //     // 向共享内存中写入数据
    //     snprintf(shmaddr, SIZE, "Client write: %c", ch);
    //     sleep(2);
    // }

    sprintf(shmaddr, "quit");

    // 4. 共享内存与进程地址空间解绑
    int n = shmdt(shmaddr);
    if(n == -1)
    {
        perror("Client# shmdt");
        exit(4);
    }
    log("Client# detach shm done", DEBUG) << "shmid:" << shmid << std::endl;
    //sleep(7);

    // 客户端只管使用共享内存，不需要关闭释放

    CloseFifo(fd);

    return 0;
}